package cn.yuxiaoyuan.util;

import cn.yuxiaoyuan.domain.GeoSearchResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.*;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author solargen
 * @version 1.0
 * @date 2025/6/28 10:52
 */
@Component
public class RedisUtil {
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;
    public List<GeoSearchResult> searchGeo(String key, double longitude, double latitude,double radius, Long limit){
        //指定中心坐标，千米为单位
        Circle circle = new Circle(new Point(longitude,latitude), new Distance(radius, Metrics.KILOMETERS));
        //GEO搜索的参数
        RedisGeoCommands.GeoRadiusCommandArgs args =RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs();
        //结果中包含 距离
        args.includeDistance()
                //结果中包含坐标
                .includeCoordinates()
                //按照中心点距离近到远排序
                .sortAscending()
                //匹配前几个司机
                .limit(limit);
        GeoResults<RedisGeoCommands.GeoLocation<Object>> geoResults = redisTemplate.opsForGeo().radius(key, circle, args);
        //拿到GEO结果列表
        List<GeoResult<RedisGeoCommands.GeoLocation<Object>>> geoResultList = geoResults.getContent();

        List<GeoSearchResult> collect = geoResultList.stream().map(geoResult -> {
            //拿到距离
            double distance = geoResult.getDistance().getValue();
            //单位
            String unit = geoResult.getDistance().getUnit();
            Object member = geoResult.getContent().getName();//司机的id
            double lon = geoResult.getContent().getPoint().getX();//司机的坐标
            double lat = geoResult.getContent().getPoint().getY();//司机的坐标
            return new GeoSearchResult(distance, unit, member, lon, lat);
        }).collect(Collectors.toList());
        //返回的是司机的id
        return collect;
    }
}
